package com.lilingguo.easyserver.pojo;

import com.lilingguo.easyserver.container.Container;

import java.io.*;
import java.util.Set;

/**
 * 持久化类
 * 用于将服务信息序列化存储
 *
 * @Author: 黎铃果
 * @Date: 2020/05/28 16:31
 */
public class Persistence {

    /**
     * 数据持久化路径
     */
    private String path;
    /**
     * 记录是否已完成加载
     */
    private boolean loaded = false;
    /**
     * 存储文件名
     */
    private static final String FILE_NAME = "EasyServer.data";

    /**
     * 带参构造方法
     * 当路径(@param path)可用时，使用 path/FILE_NAME 作为存储文件路径
     * @param path 路径
     */
    public Persistence(String path) {
        this.path = path;
        try {
            File dir = new File(path);
            if (dir.isFile()) {
                this.path = null;
                return;
            }
            dir.mkdirs();
            File file = new File(dir, Persistence.FILE_NAME);
            if (file.isDirectory()) {
                this.path = null;
            }
            if (!file.exists()) {
                file.createNewFile();
            }
            this.path = file.getAbsolutePath();
        } catch (Exception e) {
            this.path = null;
        }
    }

    public boolean isLoaded() {
        return loaded;
    }

    /**
     * 保存序列化数据
     * @param infos 服务信息集合
     */
    public void save(Set<ServiceInfo> infos) {
        assert checkPath();
        ObjectOutputStream oos = null;
        try {
            oos = new ObjectOutputStream(new FileOutputStream(this.path));
            oos.writeObject(infos);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (oos != null) {
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 加载反序列化数据
     * @param container 服务信息容器
     */
    public void load(Container container) {
        assert checkPath();
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new FileInputStream(this.path));
            Object object = ois.readObject();
            if (object instanceof Set) {
                Set<ServiceInfo> set = (Set<ServiceInfo>) object;
                for (ServiceInfo info : set) {
                    container.saveInfo(info);
                }
            }
        } catch (IOException | ClassNotFoundException e) {
            new File(this.path).deleteOnExit();
        } finally {
            loaded = true;
            if (ois != null) {
                try {
                    ois.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 判断存储文件路径可用
     * @return 判断结果
     */
    private boolean checkPath() {
        if (this.path == null) {
            return false;
        }
        File file = new File(this.path);
        if (file.isDirectory()) {
            return false;
        }
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                return false;
            }
        }
        return true;
    }
}
